<template>
  <div class="edit-align-line">
    <div
      v-for="item in line.lineArr"
      :key="item"
      class="line"
      :class="[
        item.includes('row') ? 'row' : 'col',
        line.select[item] && 'visible',
      ]"
      :style="useComponentStyle(line.select[item])"
    />
  </div>
</template>

<script>
import { mapGetters } from 'vuex'
import throttle from 'lodash/throttle'
import cloneDeep from 'lodash/cloneDeep'
import { setComponentPosition } from '@/utils'
export default {
  computed: {
    ...mapGetters('chartEdit', ['fetchTargetIndex']),
    // * 吸附距离
    ...mapGetters(['chartAlignRange', 'editCanvas', 'editCanvasConfig', 'targetChart', 'componentList', 'mousePosition']),
    // 画布坐标
    canvasPositionList () {
      return {
        id: '0',
        attr: {
          w: cloneDeep(this.editCanvasConfig.width),
          h: cloneDeep(this.editCanvasConfig.height),
          x: 0,
          y: 0,
          offsetX: 0,
          offsetY: 0,
          zIndex: 0
        }
      }
    },
    // 当前目标
    selectTarget () {
      return this.componentList[this.fetchTargetIndex()]
    },
    selectAttr () {
      return this.selectTarget?.attr || {}
    },
    selectId () {
      return this.targetChart.selectId
    }
  },
  data () {
    return {
      // * 线条集合
      line: {
        // 行横向row（上中下），列竖线col（左中右）
        lineArr: ['rowt', 'rowc', 'rowb', 'coll', 'colc', 'colr'],
        // 展示线
        select: new Map(),
        // 已经吸附
        sorptioned: {
          x: false,
          y: false
        }
      }
    }
  },
  methods: {
    // * 位置计算
    useComponentStyle (attr) {
      if (!attr) return {}
      const componentStyle = {
        left: `${attr.x ? attr.x : 0}px`,
        top: `${attr.y ? attr.y : 0}px`
      }
      return componentStyle
    },
    // * 吸附判定
    isSorption (selectValue, componentValue) {
      const isSorption = Math.abs(selectValue - componentValue) <= this.chartAlignRange
      return isSorption
    },
  },
  watch: {
    // * 取消对齐线
    'editCanvas.isDrag' (val) {
      if (!val) {
        this.line.select={}
        this.line.sorptioned.y = false
      }
    },
  },
  created () {
    this.$watch(
      'mousePosition',
      throttle(() => {
        try {
          if (!this.editCanvas.isDrag || this.selectId.length !== 1) return
          // 获取目标组件数据

          const selectW = this.selectAttr.w
          const selectH = this.selectAttr.h

          // 距离左侧
          const selectLeftX = this.selectAttr.x
          const selectHalfX = selectLeftX + selectW / 2
          const selectRightX = selectLeftX + selectW
          const seletX = [selectLeftX, selectHalfX, selectRightX]

          // 距离顶部
          const selectTopY = this.selectAttr.y
          const selectHalfY = selectTopY + selectH / 2
          const selectBottomY = selectTopY + selectH
          const selectY = [selectTopY, selectHalfY, selectBottomY]

          this.line.select={}
          this.line.sorptioned.y = false
          // 循环查询所有组件数据
          const componentList = this.componentList.map(e => {
            return {
              id: e.id,
              attr: e.attr
            }
          })
          componentList.push(this.canvasPositionList)
          // 传入画布数据
          this.line.lineArr.forEach(lineItem => {
            componentList.forEach((component) => {
              // 排除自身
              if (this.selectId[0] === component.id) return
              const componentW = component.attr.w
              const componentH = component.attr.h

              // 距离左侧
              const componentLeftX = component.attr.x
              const componentHalfX = componentLeftX + componentW / 2
              const componentRightX = componentLeftX + componentW
              const componentX = [componentLeftX, componentHalfX, componentRightX]

              // 距离顶部
              const componentTopY = component.attr.y
              const componentHalfY = componentTopY + componentH / 2
              const componentBottomY = componentTopY + componentH
              const componentY = [componentTopY, componentHalfY, componentBottomY]

              // 横线对比的是 Y
              if (lineItem.includes('rowt')) {
                // 顶部
                if (this.isSorption(selectTopY, componentTopY)) {
                  this.line.select[lineItem]={ y: componentTopY }
                  setComponentPosition(this.selectTarget, selectLeftX, componentTopY)
                }
                if (this.isSorption(selectTopY, componentHalfY)) {
                  this.line.select[lineItem]={ y: componentHalfY }
                  setComponentPosition(this.selectTarget, selectLeftX, componentHalfY)
                }
                if (this.isSorption(selectTopY, componentBottomY)) {
                  this.line.select[lineItem] ={ y: componentBottomY }
                  setComponentPosition(this.selectTarget, selectLeftX, componentBottomY)
                }
              }
              if (lineItem.includes('rowc')) {
                // 顶部
                if (this.isSorption(selectHalfY, componentTopY)) {
                  this.line.select[lineItem]= { y: componentTopY }
                  setComponentPosition(this.selectTarget, selectLeftX, componentTopY - selectH / 2)
                }
                if (this.isSorption(selectHalfY, componentHalfY)) {
                  this.line.select[lineItem]= { y: componentHalfY }
                  setComponentPosition(this.selectTarget, selectLeftX, componentHalfY - selectH / 2)
                }
                if (this.isSorption(selectHalfY, componentBottomY)) {
                  this.line.select[lineItem]= { y: componentBottomY }
                  setComponentPosition(this.selectTarget, selectLeftX, componentBottomY - selectH / 2)
                }
              }
              if (lineItem.includes('rowb')) {
                // 顶部

                if (this.isSorption(selectBottomY, componentTopY)) {
                  this.line.select[lineItem]={ y: componentTopY }
                  setComponentPosition(this.selectTarget, selectLeftX, componentTopY - selectH)
                }
                if (this.isSorption(selectBottomY, componentHalfY)) {
                  this.line.select[lineItem]={ y: componentHalfY }
                  setComponentPosition(this.selectTarget, selectLeftX, componentHalfY - selectH)
                }
                if (this.isSorption(selectBottomY, componentBottomY)) {
                  this.line.select[lineItem]={ y: componentBottomY }
                  setComponentPosition(this.selectTarget, selectLeftX, componentBottomY - selectH)
                }
              }

              // 纵线对比的是 X
              if (lineItem.includes('coll')) {
                if (this.isSorption(selectLeftX, componentLeftX)) {
                  this.line.select[lineItem] ={ x: componentLeftX }
                  setComponentPosition(this.selectTarget, componentLeftX, selectTopY)
                }
                if (this.isSorption(selectLeftX, componentHalfX)) {
                  this.line.select[lineItem] ={ x: componentHalfX }
                  setComponentPosition(this.selectTarget, componentHalfX, selectTopY)
                }
                if (this.isSorption(selectLeftX, componentRightX)) {
                  this.line.select[lineItem] ={ x: componentRightX }
                  setComponentPosition(this.selectTarget, componentRightX, selectTopY)
                }
              }
              if (lineItem.includes('colc')) {
                if (this.isSorption(selectHalfX, componentLeftX)) {
                  this.line.select[lineItem] ={ x: componentLeftX }
                  setComponentPosition(this.selectTarget, componentLeftX - selectW / 2, selectTopY)
                }
                if (this.isSorption(selectHalfX, componentHalfX)) {
                  this.line.select[lineItem] ={ x: componentHalfX }
                  setComponentPosition(this.selectTarget, componentHalfX - selectW / 2, selectTopY)
                }
                if (this.isSorption(selectHalfX, componentRightX)) {
                  this.line.select[lineItem] ={ x: componentRightX }
                  setComponentPosition(this.selectTarget, componentRightX - selectW / 2, selectTopY)
                }
              }
              if (lineItem.includes('colr')) {
                if (this.isSorption(selectRightX, componentLeftX)) {
                  this.line.select[lineItem]= { x: componentLeftX }
                  setComponentPosition(this.selectTarget, componentLeftX - selectW, selectTopY)
                }
                if (this.isSorption(selectRightX, componentHalfX)) {
                  this.line.select[lineItem]= { x: componentHalfX }
                  setComponentPosition(this.selectTarget, componentHalfX - selectW, selectTopY)
                }
                if (this.isSorption(selectRightX, componentRightX)) {
                  this.line.select[lineItem]= { x: componentRightX }
                  setComponentPosition(this.selectTarget, componentRightX - selectW, selectTopY)
                }
              }
            })
          })
        } catch (err) {
          console.log(err)
        }
      }, 200),
      {
        deep: true
      }
    )
  },
}
</script>

<style lang="scss" scoped>
.edit-align-line {
  .line {
    z-index: 1;
    position: absolute;
    top: 0;
    left: 0;
    display: none;
    border: 1px solid #51d6a9;
    opacity: 0.7;
    &.visible {
      display: block;
    }
  }
  .row {
    width: 100%;
  }
  .col {
    height: 100%;
  }
}
</style>